# -*- coding: utf-8 -*-
"""
Created on Tue Aug 24 20:31:07 2021

@author: gejiangfan
"""

from flask import Flask, request, jsonify
import numpy as np
import time
import requests
import argparse
import os
import json
import base64
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer

USER_NAME = ['lxc', 'gjf']
USER_PWD = {'lxc': 'abc@123', 'gjf': '123@abc'}
SECRET_KEY = 'abcdefghijklmn'
BARCODE_LIST = ["D88888888", "E33333333"]
INV_ORG_ID_LIST = ["200592", "200591"]


def generate_token(user_id, expiration=3600):
    print("--------- start generate token --------------")
    s = Serializer(SECRET_KEY, expires_in=expiration)
    start_time = int(time.time())
    expire_time = time.strftime("%Y-%m-%d-%H:%M:%S", time.localtime(start_time + expiration))
    token = s.dumps({"id": user_id}).decode("ascii")
    return token, expire_time


def check_param_legal(req_key: str, req_value: str, value_legal_set: list = None) -> (bool, str):
    print("--------- check param  {0} : {1} --------------".format(req_key, req_value))
    if not req_value:
        rsp_json = jsonify({"IsError": True,
                            "Message": "{0} does not exist".format(req_key),
                            "ErrorCode": "-2"})
        return False, rsp_json

    if value_legal_set and req_value not in value_legal_set:
        rsp_json = jsonify({"IsError": True,
                            "Message": "{0} is illegal".format(req_key),
                            "ErrorCode": "-2"})
        return False, rsp_json
    return True, None


def create_app():
    app = Flask(__name__,
                root_path=os.getcwd())

    @app.route('/SignIn', methods=['POST'])
    def login():
        print("--------- receive request --------------")
        if request.content_type.startswith("application/json"):
            try:
                json_data = request.json
                if not isinstance(json_data, dict):
                    return jsonify({"IsError": True,
                                    "Message": "Invalid json data",
                                    "ErrorCode": -6})
            except Exception as e:
                return jsonify({"IsError": True,
                                "Message": "Invalid json data",
                                "ErrorCode": -6})
            user_name = json_data.get("User")
            print("--------- User Name {} --------------".format(user_name))
            user_pwd = json_data.get("Pwd")
            print("--------- User Pwd {} --------------".format(user_pwd))
            if (user_name is None) or (user_name not in USER_NAME):
                print("--------- Invalid User Name --------------")
                return jsonify({"IsError": True,
                                "Message": "Invalid User Name",
                                "ErrorCode": -6})
            elif user_pwd != USER_PWD[user_name]:
                print("--------- Invalid User Pwd --------------")
                return jsonify({"IsError": True,
                                "Message": "User Name OR Password Error",
                                "ErrorCode": -7})
            else:
                print("--------- accept data success --------------")
                token, expire_time = generate_token(user_name)
                message = {"Expired": expire_time,
                           "Token": token,
                           "TokenType": "Bearer"}
                return jsonify({"Data": message,
                                "IsError": False,
                                "Message": "",
                                "ErrorCode": 0})
        else:
            return jsonify({"IsError": True,
                            "Message": "Invalid content type",
                            "ErrorCode": -5})

    @app.route('/Query', methods=['POST'])
    def query():
        print("--------- receive request --------------")
        if request.content_type.startswith("application/json"):
            try:
                token = request.headers.get("Authorization")
                s = Serializer(SECRET_KEY)
                user = s.loads(token.replace("Bearer ", ""))
            except Exception as e:
                return jsonify({"IsError": True,
                                "Message": "Invalid token",
                                "ErrorCode": -7})
            try:
                json_data = request.json
                if not isinstance(json_data, dict):
                    return jsonify({"IsError": True,
                                    "Message": "Invalid json data",
                                    "ErrorCode": -6})
            except Exception as e:
                return jsonify({"IsError": True,
                                "Message": "Invalid json data",
                                "ErrorCode": -6})
            bar_code = json_data.get("BARCODE")
            project_code = json_data.get("PROJECTCODE")
            logical_code = json_data.get("LOGICAL_CODE")
            inv_org_id = json_data.get("INVORGID")

            ok, rsp = check_param_legal("BARCODE", bar_code, BARCODE_LIST)
            if not ok:
                return rsp
            ok, rsp = check_param_legal("PROJECTCODE", project_code)
            if not ok:
                return rsp
            ok, rsp = check_param_legal("LOGICAL_CODE", logical_code)
            if not ok:
                return rsp
            ok, rsp = check_param_legal("INVORGID", inv_org_id, INV_ORG_ID_LIST)
            if not ok:
                return rsp

            message = [
                {"BARCODE": bar_code,
                 "MODEL_NAME": "BCD-176M",
                 "CUSTOMER_MODEL": "BCD-176M",
                 "CONSUME_COUNTRY": "国内",
                 "PROJECTCODE": project_code,
                 "INV_ORG_ID": inv_org_id,
                 "LOGICAL_CODE": logical_code
                 }
            ]
            return jsonify({"Data": message,
                            "IsError": False,
                            "Message": "",
                            "ErrorCode": 0})
        else:
            return jsonify({"IsError": True,
                            "Message": "Invalid content type",
                            "ErrorCode": -5})

    @app.route('/Upload', methods=['POST'])
    def upload():
        print("--------- receive request --------------")
        if request.content_type.startswith("application/json"):
            try:
                json_data = request.json
                if not isinstance(json_data, dict):
                    return jsonify({"IsError": True,
                                    "Message": "Invalid json data",
                                    "ErrorCode": -6})
            except Exception as e:
                return jsonify({"IsError": True,
                                "Message": "Invalid json data",
                                "ErrorCode": -6})
            bar_code = json_data.get("BARCODE")
            inv_org_id = json_data.get("INV_ORG_ID")
            device_code = json_data.get("DEVICE_CODE")

            ok, rsp = check_param_legal("BARCODE", bar_code, BARCODE_LIST)
            if not ok:
                return rsp
            ok, rsp = check_param_legal("INV_ORG_ID", inv_org_id, INV_ORG_ID_LIST)
            if not ok:
                return rsp
            ok, rsp = check_param_legal("DEVICE_CODE", device_code)
            if not ok:
                return rsp

            print(request.json)
            return jsonify({"Data": True,
                            "IsError": False,
                            "Message": "success",
                            "ErrorCode": 0,
                            "updated_data":
                                {"BARCODE": bar_code,
                                 "DATETIME_ACQUISITION": json_data.get("INV_ORG_ID"),
                                 "DEVICE_CODE": device_code,
                                 "INV_ORG_ID": inv_org_id,
                                 "TEST_STATUS": json_data.get("TEST_STATUS"),
                                 "WORKCENTER_CODE": json_data.get("WORKCENTER_CODE"),
                                 "detectionLine": json_data.get("detectionLine"),
                                 "totalErrCode": json_data.get("totalErrCode"),
                                 "totalSteps": json_data.get("totalSteps"),
                                 "totalTest_conditions": json_data.get("totalTest_conditions"),
                                 "user": json_data.get("user"),
                                 "detail": [
                                     {"Args": [
                                         {"comment": json_data.get("comment"),
                                         "result": json_data.get("result"),
                                         "test_conditions": json_data.get("test_conditions"),
                                         "value": json_data.get("value")}
                                         ]}
                                 ]
                                }
                            })
        else:
            return jsonify({"IsError": True,
                            "Message": "Invalid content type",
                            "ErrorCode": -5})

    @app.route('/infer', methods=['POST'])
    def ai_infer():
        print("--------- receive request --------------")
        if request.content_type.startswith("application/json"):
            try:
                json_data = request.json
                if not isinstance(json_data, dict):
                    return jsonify({"IsError": True,
                                    "Message": "Invalid json data",
                                    "ErrorCode": -6})
            except Exception as e:
                return jsonify({"IsError": True,
                                "Message": "Invalid json data",
                                "ErrorCode": -6})
            image_infos = json_data.get("Files", None)
            # print("--------- get files {}--------------".format(image_infos))
            for info in image_infos:
                file_name = info.get("FileName")
                print("--------- file_name {}--------------".format(file_name))

                image_content = info.get("ImageData")
                image_bytes = base64.b64decode(image_content)
                file_path = os.path.join("./tmp_imgs", file_name)
                if not os.path.exists(os.path.dirname(file_path)):
                    os.makedirs(os.path.dirname(file_path))
                print("--------- file path {}--------------".format(file_path))
                with open(file_path, 'wb') as f:
                    f.write(image_bytes)
            return jsonify({"IsError": False,
                            "Message": "receive success",
                            "ErrorCode": 0})
        else:
            return jsonify({"IsError": True,
                            "Message": "Invalid content type",
                            "ErrorCode": -5})

    return app


def main():
    parser = argparse.ArgumentParser(description="MES Demo")
    parser.add_argument("--host",
                        default="127.0.0.1")
    parser.add_argument("--port",
                        default=8888)

    args = parser.parse_args()
    app = create_app()
    app.run(host=args.host, port=args.port, threaded=False, debug=False)


if __name__ == "__main__":
    exit(main())
